#pragma once

namespace amc{
    unsigned short type(const std::vector<unsigned char>& data){
        return data[0x1*2]|(data[0x1*2+1]<<8);
    }
    std::string version(std::vector<unsigned char>& data){
        return std::to_string(data[0xa*2])+std::to_string(data[0xa*2+1]);
    }
    unsigned short sampling(std::vector<unsigned char>& data,unsigned short value=0){
        return 0;
    }
    unsigned char trigger(std::vector<unsigned char>& data,unsigned char value=-1){
        return 0;
    }
    unsigned char status(std::vector<unsigned char>& data,unsigned char value=0){
        return 0;
    }
    std::vector<unsigned char> channel_enable(std::vector<unsigned char>& data){
        return {};
    }
    std::vector<unsigned char> channel_enable(std::vector<unsigned char>& data,std::vector<unsigned char>& value){
        return {};
    }
    std::vector<unsigned char> channel_mode(std::vector<unsigned char>& data){
        return {};
    }
    std::vector<unsigned char> channel_mode(std::vector<unsigned char>& data,std::vector<unsigned char>& value){
        return {};
    }
    std::vector<unsigned char> gain(std::vector<unsigned char>& data){
        return {};
    }
    std::vector<unsigned char> gain(std::vector<unsigned char>& data,std::vector<unsigned char>& value){
        return {};
    }
    std::vector<unsigned char> coupling(std::vector<unsigned char>& data){
        return {};
    }
    std::vector<unsigned char> coupling(std::vector<unsigned char>& data,std::vector<unsigned char>& value){
        return {};
    }
    unsigned short samplen(std::vector<unsigned char>& data,unsigned short value=0){
        return 0;
    }
    int time(std::vector<unsigned char>& data,int value=-1){
        return 0;
    }
    unsigned int filter(std::vector<unsigned char>& data,unsigned int value=0){
        return 0;
    }
}
namespace amc7376{
    unsigned short sampling(std::vector<unsigned char>& data,unsigned short value=0){
        if(value!=0){
            data[0x4*2]=(value*10)&0xff;
            data[0x4*2+1]=(value*10)>>8;
        }
        return (data[0x4*2]|(data[0x4*2+1]<<8))/10;
    }
    unsigned char trigger(std::vector<unsigned char>& data,unsigned char value=-1){
        if(value!=-1) data[0x7*2]=value;
        return data[0x7*2]&0x1;
    }
    unsigned char status(std::vector<unsigned char>& data,unsigned char value=0){
        if(value!=0) data[0x6*2]=value;
        return data[0x6*2];
    }
    std::vector<unsigned char> channel_enable(std::vector<unsigned char>& data){
        std::vector<unsigned char> ret;
        for(int i=0;i<6;++i)
            ret.emplace_back(data[0x3*2]>>i&0x1);
        return ret;
    }
    std::vector<unsigned char> channel_enable(std::vector<unsigned char>& data,std::vector<unsigned char>& value){
        std::vector<unsigned char> ret;
        if(value.size()>0){
            for(int i=0;i<value.size();++i)
                data[0x3*2]|=value[i]<<i;
        }
        for(int i=0;i<6;++i)
            ret.emplace_back(data[0x3*2]>>i&0x1);
        return ret;
    }
    std::vector<unsigned char> channel_mode(std::vector<unsigned char>& data){
        std::vector<unsigned char> ret;
        for(int i=0;i<6;++i)
            ret.emplace_back(data[0x5*2]>>i&0x1);
        return ret;
    }
    std::vector<unsigned char> channel_mode(std::vector<unsigned char>& data,std::vector<unsigned char>& value){
        std::vector<unsigned char> ret;
        if(value.size()>0){
            for(int i=0;i<value.size();++i)
                data[0x5*2]|=value[i]<<i;
        }
        for(int i=0;i<6;++i)
            ret.emplace_back(data[0x5*2]>>i&0x1);
        return ret;
    }
    std::vector<unsigned char> gain(std::vector<unsigned char>& data){
        std::vector<unsigned char> ret;
        for(int i=0;i<12;i+=2){
            if(i<8)
                ret.emplace_back(data[0x8*2]>>i&0x3);
            else
                ret.emplace_back(data[0x8*2+1]>>(i-8)&0x3);
        }
        return ret;
    }
    std::vector<unsigned char> gain(std::vector<unsigned char>& data,std::vector<unsigned char>& value){
        std::vector<unsigned char> ret;
        if(value.size()>0){
            for(int i=0;i<value.size();++i){
                if(2*i<8)
                    data[0x8*2]|=value[i]<<2*i&0x3;
                else
                    data[0x8*2+1]|=value[i]<<(2*i-8)&0x3;
            }
        }
        for(int i=0;i<12;i+=2){
            if(i<8)
                ret.emplace_back(data[0x8*2]>>i&0x3);
            else
                ret.emplace_back(data[0x8*2+1]>>(i-8)&0x3);
        }
        return ret;
    }
    std::vector<unsigned char> coupling(std::vector<unsigned char>& data){
        std::vector<unsigned char> ret;
        for(int i=0;i<6;++i)
            ret.emplace_back(data[0x9*2]>>i&0x1);
        return ret;
    }
    std::vector<unsigned char> coupling(std::vector<unsigned char>& data,std::vector<unsigned char>& value){
        std::vector<unsigned char> ret;
        if(value.size()>0){
            for(int i=0;i<value.size();++i)
                data[0x9*2]|=value[i]<<i;
        }
        for(int i=0;i<6;++i)
            ret.emplace_back(data[0x9*2]>>i&0x1);
        return ret;
    }
    unsigned short samplen(std::vector<unsigned char>& data,unsigned short value=0){
        if(value!=0){
            data[0xb*2]=(value/100);
            data[0xb*2+1]=(value/100)>>8;
        }
        return (data[0xb*2]|(data[0xb*2+1]<<8))*100;
    }
    int time(std::vector<unsigned char>& data,int value=-1){
        if(value!=-1) data[0xc*2]=value;
        return data[0xc*2]&0x1;
    }
    unsigned int filter(std::vector<unsigned char>& data,unsigned int value=0){
        return 0;
    }
}
namespace amc7377{
    unsigned short sampling(std::vector<unsigned char>& data,unsigned short value=0){
        if(value!=0){
            data[0x4*2]=value&0xff;
            data[0x4*2+1]=value>>8;
        }
        return data[0x4*2]|(data[0x4*2+1]<<8);
    }
    unsigned char trigger(std::vector<unsigned char>& data,unsigned char value=-1){
        if(value!=-1) data[0x7*2]=value;
        return data[0x7*2]&0x1;
    }
    unsigned char status(std::vector<unsigned char>& data,unsigned char value=0){
        if(value!=0) data[0x6*2]=value;
        return data[0x6*2];
    }
    std::vector<unsigned char> channel_enable(std::vector<unsigned char>& data){
        std::vector<unsigned char> ret;
        for(int i=0;i<16;++i){
            if(i<8)
                ret.emplace_back(data[0x3*2]>>i&0x1);
            else
                ret.emplace_back(data[0x3*2+1]>>(i-8)&0x1);
        }
        return ret;
    }
    std::vector<unsigned char> channel_enable(std::vector<unsigned char>& data,std::vector<unsigned char>& value){
        std::vector<unsigned char> ret;
        if(value.size()>0){
            for(int i=0;i<value.size();++i){
                if(i<8)
                    data[0x3*2]|=value[i]<<i;
                else
                    data[0x3*2+1]|=value[i]<<(i-8);
            }
        }
        for(int i=0;i<16;++i){
            if(i<8)
                ret.emplace_back(data[0x3*2]>>i&0x1);
            else
                ret.emplace_back(data[0x3*2+1]>>(i-8)&0x1);
        }
        return ret;
    }
    std::vector<unsigned char> channel_mode(std::vector<unsigned char>& data){
        return std::vector<unsigned char>();
    }
    std::vector<unsigned char> channel_mode(std::vector<unsigned char>& data,std::vector<unsigned char>& value){
        return std::vector<unsigned char>();
    }
    std::vector<unsigned char> gain(std::vector<unsigned char>& data){
        return std::vector<unsigned char>();
    }
    std::vector<unsigned char> gain(std::vector<unsigned char>& data,std::vector<unsigned char>& value){
        return std::vector<unsigned char>();
    }
    std::vector<unsigned char> coupling(std::vector<unsigned char>& data){
        return std::vector<unsigned char>();
    }
    std::vector<unsigned char> coupling(std::vector<unsigned char>& data,std::vector<unsigned char>& value){
        return std::vector<unsigned char>();
    }
    unsigned short samplen(std::vector<unsigned char>& data,unsigned short value=0){
        if(value!=0) {
            data[0xb*2]=(value/100)&0xff;
            data[0xb*2+1]=(value/100)>>8;
        }
        return (data[0xb*2]|(data[0xb*2+1]<<8))*100;
    }
    int time(std::vector<unsigned char>& data,int value=-1){
        if(value!=-1) data[0xc*2]=value;
        return data[0xc*2]&0x1;
    }
    unsigned int filter(std::vector<unsigned char>& data,unsigned int value=0){
        return 0;
    }
}
namespace amc7511{
    unsigned short sampling(std::vector<unsigned char>& data, unsigned short value=0){
        if(value!=0){
            data[0x4*2]=value&0xff;
            data[0x4*2+1]=value>>8;
        }
        return data[0x4*2]|(data[0x4*2+1]<<8);
    }
    unsigned char trigger(std::vector<unsigned char>& data,unsigned char value=-1){
        if(value!=-1) data[0x7*2]=value;
        return data[0x7*2]&0x1;
    }
    unsigned char status(std::vector<unsigned char>& data,unsigned char value=0){
        if(value!=0) data[0x6*2]=value;
        return data[0x6*2];
    }
    std::vector<unsigned char> channel_enable(std::vector<unsigned char>& data){
        std::vector<unsigned char> ret;
        for(int i=0;i<32;++i){
            if(i<8)
                ret.emplace_back(data[0x3*2]>>i&0x1);
            else if(i<16)
                ret.emplace_back(data[0x3*2+1]>>(i-8)&0x1);
            else if(i<24)
                ret.emplace_back(data[0x3*2+2]>>(i-16)&0x1);
            else
                ret.emplace_back(data[0x3*2+3]>>(i-24)&0x1);
        }
        return ret;
    }
    std::vector<unsigned char> channel_enable(std::vector<unsigned char>& data,std::vector<unsigned char>& value){
        std::vector<unsigned char> ret;
        if(value.size()>0){
            for(int i=0;i<value.size();++i){
                if(i<8)
                    data[0x3*2]|=value[i]<<i;
                else if(i<16)
                    data[0x3*2+1]|=value[i]<<(i-8);
                else if(i<24)
                    data[0x3*2+2]|=value[i]<<(i-16);
                else
                    data[0x3*2+3]|=value[i]<<(i-24);
            }
        }
        for(int i=0;i<32;++i){
            if(i<8)
                ret.emplace_back(data[0x3*2]>>i&0x1);
            else if(i<16)
                ret.emplace_back(data[0x3*2+1]>>(i-8)&0x1);
            else if(i<24)
                ret.emplace_back(data[0x3*2+2]>>(i-16)&0x1);
            else
                ret.emplace_back(data[0x3*2+3]>>(i-24)&0x1);
        }
        return ret;
    }
    std::vector<unsigned char> channel_mode(std::vector<unsigned char>& data){
        return std::vector<unsigned char>();
    }
    std::vector<unsigned char> channel_mode(std::vector<unsigned char>& data,std::vector<unsigned char>& value){
        return std::vector<unsigned char>();
    }
    std::vector<unsigned char> gain(std::vector<unsigned char>& data){
        return std::vector<unsigned char>();
    }
    std::vector<unsigned char> gain(std::vector<unsigned char>& data,std::vector<unsigned char>& value){
        return std::vector<unsigned char>();
    }
    std::vector<unsigned char> coupling(std::vector<unsigned char>& data){
        return std::vector<unsigned char>();
    }
    std::vector<unsigned char> coupling(std::vector<unsigned char>& data,std::vector<unsigned char>& value){
        return std::vector<unsigned char>();
    }
    unsigned short samplen(std::vector<unsigned char>& data,unsigned short value=0){
        return 0;
    }
    int time(std::vector<unsigned char>& data,int value=-1){
        if(value!=-1) data[0xc*2]=value;
        return data[0xc*2]&0x1;
    }
    unsigned int filter(std::vector<unsigned char>& data,unsigned int value=0){
        if(value!=0){
            data[0x8*2]= value&0xff;
            data[0x8*2+1]= value>>8&0xff;
            data[0x8*2+2]= value>>16&0xff;
            data[0x8*2+3]= value>>24&0xff;
        }
        return (data[0x8*2+3]<<24)|(data[0x8*2+2]<<16)|(data[0x8*2+1]<<8)|data[0x8*2];
    }
}